Type TVisual
	Const debug:Byte=True
	Global _list:TList=New TList
	Field _link:TLink
	Field _active:Byte=True
	Field _debug:Byte=False
	Field _style:TStyle=New TStyle
	
	Function render()
		For Local v:TVisual=EachIn _list
			Local allowDraw:Byte=False
			If(v._active)
				If (Not v._debug)
					allowDraw=True
				ElseIf(debug)
					allowDraw=True
				EndIf
			EndIf
			If (allowDraw)
				v.setStyle()
				v.draw()
			EndIf
		Next
	End Function
	
	Method Alpha:TVisual(alpha#)
		_style._a=alpha
		Return Self
	End Method
	Method Color:TVisual(red%,green%,blue%)
		_style._r=red
		_style._g=green
		_style._b=blue
		Return Self
	End Method
	Method Blend:TVisual(blend%)
		_style._blend=blend
		Return Self
	End Method
	
	Method SetStyle()
		SetAlpha _style._a
		SetColor _style._r,_style._g,_style._b
		SetBlend _style._blend
	End Method
	
	Method draw() Abstract
	Method setPosition:TVisual(x#,y#) Abstract
	Method move:TVisual(x#,y#) Abstract
	Method getX#() Abstract
	Method getY#() Abstract
	
	Method setSize:TVisual(width#,height#) Abstract
	Method resize:TVisual(width#,height#) Abstract
	Method getWidth#() Abstract
	Method getHeight#() Abstract
	
	Method setAngle:TVisual(angle#) Abstract
	Method turn:TVisual(angle#) Abstract
	Method getAngle#() Abstract
End Type

Type TStyle
	Field _r%=255
	Field _g%=255
	Field _b%=255
	Field _a#=1.0
	Field _blend%=SOLIDBLEND
End Type

Type TPoint Extends TVisual
	Field _x#,_y#
	
	Function Create:TPoint()
		Local d:TPoint=New TPoint
		
		d._link=_list.AddLast(d)
		
		Return d
	End Function
	
	Method draw()
'		Local x#=_x
'		Local y#=_y
'		TCamera.projectXY(x,y)
'		
'		Plot(x, y)
	End Method
	
	Method setPosition:TPoint(x#,y#)
		_x=x
		_y=y
		Return Self
	End Method
	Method move:TPoint(x#,y#)
		_x:+x
		_y:+y
		Return Self
	End Method
	Method getX#()
		Return _x
	End Method
	Method getY#()
		Return _y
	End Method
	
	Method setSize:TPoint(width#,height#)
		Return Self
	End Method
	Method resize:TPoint(width#,height#)
		Return Self
	End Method
	Method getWidth#()
		Return 0
	End Method
	Method getHeight#()
		Return 0
	End Method
	
	Method setAngle:TVisual(angle#)
		Return Self
	End Method
	Method turn:TVisual(angle#)
		Return Self
	End Method
	Method getAngle#()
		Return 0
	End Method
End Type

Type TLine Extends TVisual
	Field _d:TPoint[2]
	
	Function Create:TLine(x1#,y1#,x2#,y2#)
		Local l:TLine=New TLine
		
		l._d[0]=TPoint.Create().setPosition(x1,y1)
		l._d[0]._active=False
		l._d[1]=TPoint.Create().setPosition(x2,y2)
		l._d[1]._active=False
		
		l._link=_list.AddLast(l)
		
		Return l
	End Function
	
	Method draw()
		Local x1#=_d[0]._x
		Local y1#=_d[0]._y
		Local x2#=_d[1]._x
		Local y2#=_d[1]._y
		TCamera.projectXY(x1,y1)
		TCamera.projectXY(x2,y2)
		
		DrawLine(x1, y1, x2, y2)
	End Method
	
	Method setPosition:TLine(x#,y#)
		Return Self
	End Method
	Method move:TLine(x#,y#)
		_d[0].move(x,y)
		_d[1].move(x,y)
		Return Self
	End Method
	Method getX#()
		Return 0
	End Method
	Method getY#()
		Return 0
	End Method
	Method point:TPoint(ind%)
		Return _d[ind]
	End Method
	
	Method setSize:TLine(width#,height#)
		Return Self
	End Method
	Method resize:TLine(width#,height#)
		Return Self
	End Method
	Method getWidth#()
		Return 0
	End Method
	Method getHeight#()
		Return 0
	End Method
	
	Method setAngle:TLine(angle#)
		Return Self
	End Method
	Method turn:TLine(angle#)
		Return Self
	End Method
	Method getAngle#()
		Return 0
	End Method
End Type

Type TPoly Extends TVisual
	Field _c:TPoint
	Field _d:TPoint[3]
	Field _width#,_height#
	Field _angle#
	Field _handleX#=.5
	Field _handleY#=.5
	
	Function Create:TPoly(x1#,y1#,x2#,y2#,x3#,y3#)
		Local p:TPoly=New TPoly
		
		p._c=TPoint.Create()
		p._d[0]=TPoint.Create().setPosition(x1,y1)
		p._d[1]=TPoint.Create().setPosition(x2,y2)
		p._d[2]=TPoint.Create().setPosition(x3,y3)
		
		Local maxX#
		Local maxY#
		For Local i%=0 To 2
			If (p._d[i]._x>maxX)
				maxX=p._d[i]._x
			EndIf
			If (p._d[i]._y>maxY)
				maxY=p._d[i]._y
			EndIf
		Next
		
		Local minX#=maxX
		Local minY#=maxY
		For Local i%=0 To 2
			If (p._d[i]._x<minX)
				minX=p._d[i]._x
			EndIf
			If (p._d[i]._y<minY)
				minY=p._d[i]._y
			EndIf
		Next
		
		For Local i%=0 To 2
			p._d[i]._x:-minX
			p._d[i]._y:-minY
		Next
		
		p._width=maxX-minX
		p._height=maxY-minY
		
		p._link=_list.AddLast(p)
		
		Return p
	End Function
	
	Method draw()
		Local tri#[]=[_d[0]._x, _d[0]._y, _d[1]._x, _d[1]._y, _d[2]._x, _d[2]._y]
		
		For Local i%=0 To 2
			tri[i*2  ]:-_width *_handleX
			tri[i*2+1]:-_height*_handleY
			
			Local dist#=dist(tri[i*2],tri[i*2+1])
			Local ang#=vecAngle(tri[i*2],tri[i*2+1]) + _angle
			
			tri[i*2  ] = angleX(ang)*dist
			tri[i*2+1] = angleY(ang)*dist
			
			tri[i*2  ]:+_c._x
			tri[i*2+1]:+_c._x
		Next
		
		TCamera.projectXY(tri[0],tri[1])
		TCamera.projectXY(tri[2],tri[3])
		TCamera.projectXY(tri[4],tri[5])
		
		DrawPoly(tri)
	End Method
	
	Method setCenter:TPoly(x#,y#)
		_handleX=x
		_handleY=y
		Return Self
	End Method
	
	Method setPosition:TPoly(x#,y#)
		_c.setPosition(x,y)
		Return Self
	End Method
	Method move:TPoly(x#,y#)
		_c.move(x,y)
		Return Self
	End Method
	Method getX#()
		Return _c._x
	End Method
	Method getY#()
		Return _c._y
	End Method
	
	Method setSize:TPoly(width#,height#)
		Return Self
	End Method
	Method resize:TPoly(width#,height#)
		Return Self
	End Method
	Method getWidth#()
		Return 0
	End Method
	Method getHeight#()
		Return 0
	End Method
	
	Method setAngle:TPoly(angle#)
		_angle=angle
		Return Self
	End Method
	Method turn:TPoly(angle#)
		_angle:+angle
		Return Self
	End Method
	Method getAngle#()
		Return _angle
	End Method
End Type

Type TOval Extends TVisual
	Field _c:TPoint
	Field _width#,_height#
	Field _angle#
	Field _handleX#=.5
	Field _handleY#=.5
	
	Function Create:TOval(width#,height#)
		Local o:TOval=New TOval
		
		o._c=TPoint.Create()
		o._width=width
		o._height=height
		
		o._link=_list.AddLast(o)
		
		Return o
	End Function
	
	Method draw()
		Local x#=_c._x
		Local y#=_c._y
		Local w#=TCamera.projectW(_width)
		Local h#=TCamera.projectH(_height)
		TCamera.projectXY(x,y)
		
		SetHandle(w*_handleX,h*_handleY)
		SetRotation(TCamera.projectR(_angle))
		
		DrawOval(x, y, w, h)
		
		SetRotation(0)
		SetHandle(0,0)
	End Method
	
	Method setPosition:TOval(x#,y#)
		_c.setPosition(x,y)
		Return Self
	End Method
	Method move:TOval(x#,y#)
		_c.move(x,y)
		Return Self
	End Method
	Method getX#()
		Return _c._x
	End Method
	Method getY#()
		Return _c._y
	End Method
	
	Method setSize:TOval(width#,height#)
		_width=width
		_height=height
		Return Self
	End Method
	Method resize:TOval(width#,height#)
		_width:*width
		_height:*height
		Return Self
	End Method
	Method getWidth#()
		Return _width
	End Method
	Method getHeight#()
		Return _height
	End Method
	
	Method setAngle:TOval(angle#)
		_angle=angle
		Return Self
	End Method
	Method turn:TOval(angle#)
		_angle:+angle
		Return Self
	End Method
	Method getAngle#()
		Return _angle
	End Method
End Type

Type TRect Extends TVisual
	Field _c:TPoint
	Field _width#,_height#
	Field _angle#
	Field _handleX#=.5
	Field _handleY#=.5
	
	Function Create:TRect(width#,height#)
		Local r:TRect=New TRect
		
		r._c=TPoint.Create()
		r._width=width
		r._height=height
		
		r._link=_list.AddLast(r)
		
		Return r
	End Function
	
	Method draw()
		Local x#=_c._x
		Local y#=_c._y
		Local w#=TCamera.projectW(_width)
		Local h#=TCamera.projectH(_height)
		TCamera.projectXY(x,y)
		
		SetHandle(w*_handleX,h*_handleY)
		SetRotation(TCamera.projectR(_angle))
		
		DrawRect(x, y, w, h)
		
		SetRotation(0)
		SetHandle(0,0)
	End Method
	
	Method setCenter:TRect(x#,y#)
		_handleX=x
		_handleY=y
		Return Self
	End Method
	
	Method setPosition:TRect(x#,y#)
		_c.setPosition(x,y)
		Return Self
	End Method
	Method move:TRect(x#,y#)
		_c.move(x,y)
		Return Self
	End Method
	Method getX#()
		Return _c._x
	End Method
	Method getY#()
		Return _c._y
	End Method
	
	Method setSize:TRect(width#,height#)
		_width=width
		_height=height
		Return Self
	End Method
	Method resize:TRect(width#,height#)
		_width:*width
		_height:*height
		Return Self
	End Method
	Method getWidth#()
		Return _width
	End Method
	Method getHeight#()
		Return _height
	End Method
	
	Method setAngle:TRect(angle#)
		_angle=angle
		Return Self
	End Method
	Method turn:TRect(angle#)
		_angle:+angle
		Return Self
	End Method
	Method getAngle#()
		Return _angle
	End Method
End Type

Type TText Extends TVisual
	Field _c:TPoint
	Field _angle#
	Field _width#,_height#
	Field _handleX#=.5,_handleY#=.5
	Field _text$
	
	Function Create:TText(text$)
		Local t:TText=New TText
		
		t._c=TPoint.Create()
		t._text=text
		t._style._blend=ALPHABLEND
		t._width=TextWidth(t._text)
		t._height=TextHeight(t._text)
		
		t._link=_list.AddLast(t)
		
		Return t
	End Function
	
	Method draw()
		Local x#=_c._x
		Local y#=_c._y
		TCamera.projectXY(x, y)
		
		SetScale(TCamera.activeCamera._zoom, TCamera.activeCamera._zoom)
		SetHandle(_width*_handleX, _height*_handleY)
		SetRotation(TCamera.projectR(_angle))
		
		DrawText(_text, x, y)
		
		SetRotation(0)
		SetHandle(0,0)
		SetScale(1,1)
	End Method
	
	Method setPosition:TText(x#,y#)
		_c.setPosition(x,y)
		Return Self
	End Method
	Method move:TText(x#,y#)
		_c.move(x,y)
		Return Self
	End Method
	Method getX#()
		Return _c._x
	End Method
	Method getY#()
		Return _c._y
	End Method
	
	Method setSize:TText(width#,height#)
		Return Self
	End Method
	Method resize:TText(width#,height#)
		Return Self
	End Method
	Method getWidth#()
		Return _width
	End Method
	Method getHeight#()
		Return _height
	End Method
	
	Method setAngle:TText(angle#)
		_angle=angle
		Return Self
	End Method
	Method turn:TText(angle#)
		_angle:+angle
		Return Self
	End Method
	Method getAngle#()
		Return _angle
	End Method
End Type

Type TImg Extends TVisual
	Field _c:TPoint
	Field _img:TImage
	Field _width#,_height#
	Field _scaleX#,_scaleY#
	Field _angle#
	
	Function Create:TImg(file$)
		Local i:TImg=New TImg
		
		i._c=TPoint.Create()
		
		i._img=LoadImage(file)
		i._width=ImageWidth(i._img)
		i._height=ImageHeight(i._img)
		
		SetImageHandle(i._img,i._width*.5,i._height*.5)
		
		i._link=_list.AddLast(i)
		
		Return i
	End Function
	
	Method draw()
		Local x#=_c._x
		Local y#=_c._y
		Local w#=TCamera.projectW(_scaleX*.5)
		Local h#=TCamera.projectH(_scaleY*.5)
		TCamera.projectXY(x,y)
		
		SetRotation(TCamera.projectR(_angle))
		SetScale(w/_width,h/_height)
		
		DrawImage(_img,x,y)
		
		SetScale(1,1)
		SetRotation(0)
	End Method
	
	Method setCenter:TImg(x#,y#)
		SetImageHandle(_img,_width*x,_height*y)
		Return Self
	End Method
	
	Method setPosition:TImg(x#,y#)
		_c.setPosition(x,y)
		Return Self
	End Method
	Method move:TImg(x#,y#)
		_c.move(x,y)
		Return Self
	End Method
	Method getX#()
		Return _c._x
	End Method
	Method getY#()
		Return _c._y
	End Method
	
	Method setSize:TImg(width#,height#)
		_scaleX=width
		_scaleY=height
		Return Self
	End Method
	Method resize:TImg(scaleX#,scaleY#)
		_scaleX:*scaleX
		_scaleY:*scaleY
		Return Self
	End Method
	Method getWidth#()
		Return _scaleX
	End Method
	Method getHeight#()
		Return _scaleY
	End Method
	
	Method setAngle:TImg(angle#)
		_angle=angle
		Return Self
	End Method
	Method turn:TImg(angle#)
		_angle:+angle
		Return Self
	End Method
	Method getAngle#()
		Return _angle
	End Method
End Type